/*
	This script file is part of the Sonic 3 A.I.R. script software distribution.
	Copyright (C) 2017-2024 by Eukaryot

	Published under the GNU GPLv3 open source software license, see license.txt
	or https://www.gnu.org/licenses/gpl-3.0.en.html
*/



//# address-hook(0x03cb3a) end(0x03cbc8)
function void fn03cb3a()
{
	objA0.mapping_offset = 0x03cc5a
	objA0.sprite_attributes = 0x030f
	objA0.render_flags |= render_flag.WORLD
	objA0.box_size.x = 0x10
	objA0.box_size.y = 0x10
	objA0.sprite_priority = 0x80

	objA0.update_address = 0x03cb66
	fn03cb66()
}


//# address-hook(0x03cb66) end(0x03cbc8)
function void fn03cb66()
{
	D0.u16 = u16[0xffffb000 + 0x14] - objA0.position.y.u16
	if (D0.s16 >= 0)
	{
		if (D0.s16 >= 0x20)
		{
			objA0.state = 1
		}
	}
	else
	{
		if (D0.s16 < -0x10)
		{
			objA0.state = 0
		}
	}

	A1 = 0xffffb000
	if (objA0.flags2a & object.flag.P1_ON_OBJECT)
	{
		objA0.flags2a &= ~object.flag.P1_ON_OBJECT
		fn03cbce()
	}

	A1 = 0xffffb04a
	if (objA0.flags2a & object.flag.P2_ON_OBJECT)
	{
		objA0.flags2a &= ~object.flag.P2_ON_OBJECT
		fn03cbce()
	}

	D1.u16 = 0x1b
	D2.u16 = 0x08
	D3.u16 = 0x09
	D4.u16 = objA0.position.x.u16
	PlatformCheckClimbOn()

	Object.animationUpdate(0x03cc4c)
	DrawOrUnloadObject()
}


//# address-hook(0x03cbce) end(0x03cc46)
function void fn03cbce()
{
	u8[A1 + 0x05] = 0x02
	objA1.velocity.y = (objA0.subtype2c & 0x02) ? -0xa00 : -0x1000
	objA1.state = char.state.STRAIGHTJUMP
	u8[A1 + 0x2a] |= char.flag.IN_AIR
	u8[A1 + 0x2a] &= ~char.flag.ON_OBJECT
	u8[A1 + 0x3d] = 0
	u8[A1 + 0x40] = 0

	if (objA0.subtype2c & 0x01)
	{
		u8[A1 + 0x20] = 0
		u8[A1 + 0x30] = (objA0.subtype2c & 0x02) ? 0 : 1		// "char.rotation.x.count"
		u8[A1 + 0x31] = 0x04									// "char.rotation.x.speed"

		if (u8[A1 + 0x2a] & char.flag.FACING_LEFT)
		{
			objA1.groundspeed = -1
			s8[A1 + 0x27] = -1
		}
		else
		{
			objA1.groundspeed = 1
			s8[A1 + 0x27] = 1
		}
	}

	playSound(SFX_SPRING)
}



// Retracting springs inside the floor

//# address-hook(0x0239e4) end(0x0239f6)
function void fn0239e4()
{
	Spring.BaseUpdate()

	// Targets:
	//  - 0x023a04	-> objA0.subtype2c == 0x00 .. 0x0f	-> Vertical spring (the only one used in the original game, and only once at that)
	//  - 0x023a20	-> objA0.subtype2c == 0x10 .. 0x1f	-> Horizontal spring
	//  - 0x023a3c	-> objA0.subtype2c == 0x20 .. 0x2f	-> Vertical spring, pointing down
	//  - 0x023a58	-> objA0.subtype2c == 0x30 .. 0x3f	-> Diagonal spring, pointing up
	//  - 0x023a88	-> objA0.subtype2c == 0x40 .. 0x4f	-> Diagonal spring, pointing down
	D0.u16 = (objA0.subtype2c >> 3) & 0x0e
	call tableLookupAddress(0x0239fa, D0.u16)
}


//# address-hook(0x023a04) end(0x023a04)
function void fn023a04()
{
	objA0.update_address = 0x023a0a
	fn023a0a()
}


//# address-hook(0x023a0a) end(0x023a1c)
function void fn023a0a()
{
	fn023ab8()

	objA0.position.y.u16 = u16[A0 + 0x34] + u8[A0 + 0x36]
	SpringVertical.Update()
}


//# address-hook(0x023a20) end(0x023a20)
function void fn023a20()
{
	objA0.update_address = 0x023a26
	fn023a26()
}


//# address-hook(0x023a26) end(0x023a38)
function void fn023a26()
{
	fn023ab8()

	objA0.position.x.u16 = u16[A0 + 0x32] + u8[A0 + 0x36]
	SpringHorizontal.Update()
}


//# address-hook(0x023a3c) end(0x023a3c)
function void fn023a3c()
{
	objA0.update_address = 0x023a42
	fn023a42()
}


//# address-hook(0x023a42) end(0x023a54)
function void fn023a42()
{
	fn023ab8()

	objA0.position.y.u16 = u16[A0 + 0x34] + u8[A0 + 0x36]
	SpringVerticalFlipped.Update()
}


//# address-hook(0x023a58) end(0x023a58)
function void fn023a58()
{
	objA0.update_address = 0x023a5e
	fn023a5e()
}


//# address-hook(0x023a5e) end(0x023a84)
function void fn023a5e()
{
	fn023ab8()

	D0.u8 = u8[A0 + 0x36]
	D1.u16 = D0.u16
	if ((objA0.flags2a & char.flag.FACING_LEFT) == 0)
	{
		D0.s16 = -D0.s16
	}
	objA0.position.x.u16 = D0.s8 + u16[A0 + 0x32]
	objA0.position.y.u16 = D1.u8 + u16[A0 + 0x34]
	SpringDiagonal.Update()
}


//# address-hook(0x023a88) end(0x023a88)
function void fn023a88()
{
	objA0.update_address = 0x023a8e
	fn023a8e()
}


//# address-hook(0x023a8e) end(0x023ab4)
function void fn023a8e()
{
	fn023ab8()

	D0.u8 = u8[A0 + 0x36]
	D1.u16 = D0.u16
	if ((objA0.flags2a & char.flag.FACING_LEFT) != 0)
	{
		D0.s16 = -D0.s16
	}
	objA0.position.x.u16 = D0.s8 + u16[A0 + 0x32]
	objA0.position.y.u16 = D1.u8 + u16[A0 + 0x34]
	SpringDiagonalFlipped.Update()
}


//# address-hook(0x023ab8) end(0x023b16)
function void fn023ab8()
{
	if (u16[A0 + 0x3a] != 0)
	{
		--u16[A0 + 0x3a]
		if (u16[A0 + 0x3a] == 0 && objA0.render_flags & render_flag.VISIBLE)
		{
			playSound(SFX_SPIKESMOVE)
		}
		return
	}

	if (u16[A0 + 0x38] != 0)
	{
		u16[A0 + 0x36] -= 0x0800
		if (s16[A0 + 0x36] < 0)
		{
			u16[A0 + 0x36] = 0
			u16[A0 + 0x38] = 0
			u16[A0 + 0x3a] = 0x3c
		}
	}
	else
	{
		u16[A0 + 0x36] += 0x0800
		if (u16[A0 + 0x36] >= 0x2000)
		{
			u16[A0 + 0x36] = 0x2000
			u16[A0 + 0x38] = 0x01
			u16[A0 + 0x3a] = 0x3c
		}
	}
}
